package com.li.net;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/*
 * 一、使用 NIO 完成网络通信的三个核心：
 * 
 * 1. 通道（Channel）：负责连接
 * 		
 * 	   java.nio.channels.Channel 接口：
 * 			|--SelectableChannel
 * 				|--SocketChannel
 * 				|--ServerSocketChannel
 * 				|--DatagramChannel
 * 
 * 				|--Pipe.SinkChannel
 * 				|--Pipe.SourceChannel
 * 
 * 2. 缓冲区（Buffer）：负责数据的存取
 * 
 * 3. 选择器（Selector）：是 SelectableChannel 的多路复用器。用于监控 SelectableChannel 的 IO 状况
 * 
 */
public class SocketChannelDemo {
	public static void main(String[] args) throws Exception {
		testSocketChannel();

	}

	public static void testSocketChannel() throws Exception{
		//1、获取通道
		InetSocketAddress inetSocketAddress=new InetSocketAddress("127.0.0.1",8888);
		SocketChannel outChannel=SocketChannel.open(inetSocketAddress);
		FileChannel inChannel=FileChannel.open(Paths.get("src/main/java/com/li/net/1.txt"), StandardOpenOption.READ);
		//2、分配buffer
		ByteBuffer byteBuffer=ByteBuffer.allocate(10);
		//3、读取本地文件，并发送到服务端
		while(inChannel.read(byteBuffer)!=-1){
			byteBuffer.flip();
			outChannel.write(byteBuffer);
			byteBuffer.clear();
			Thread.sleep(2000);
		}
		//4、关闭通道
		inChannel.close();
		outChannel.close();
	}
	
	public static void testNonBlockingSocketChannel() throws Exception{
		SocketChannel outChannel=SocketChannel.open(new InetSocketAddress("127.0.0.1",8888));
		outChannel.configureBlocking(false);
		FileChannel inChannel=FileChannel.open(Paths.get("src/main/java/com/li/net/1.txt"), StandardOpenOption.READ);
		
		ByteBuffer byteBuffer=ByteBuffer.allocate(10);
		while(inChannel.read(byteBuffer)!=1){
			byteBuffer.flip();
			outChannel.write(byteBuffer);
			byteBuffer.clear();
			Thread.sleep(2000);
		}
		
		inChannel.close();
		outChannel.close();
	}
}
